import pandas as pd
import copy
import numpy as np
import math

def knn(t,k):
    y = []
    x = []
    for d in data:
        y.append(int(d[-1]))
        x.append(d[0])
    distance=[]
    for i in range(len(x)):
        distance.append(round(abs(x[i]-t[0]),2))
    dis=copy.copy(distance)
    #print(dis)
    dis.sort()
    #print(dis)
    disc={}
    for i in range(k):
        disc[y[distance.index(dis[i])]]=disc.get(y[distance.index(dis[i])],0)+1
    #print(disc)
    d_order = sorted(disc.items(), key=lambda x: x[1], reverse=True)
    return d_order[0][0]

if __name__=="__main__":
    data = pd.read_csv('data.csv')
    test = pd.read_csv('train.csv')
    data = data.values.tolist()
    test = test.values.tolist()
    flist=[]#弱分类器系数列表
    y1=[]#实际值
    for t in range(len(test)):
        y1.append(test[t][1])
    D=[]#初始化权值分布
    for  i in range (len(test)):
        D.append(1/len(test))
    for k in (1,5):
        G = []  # 分类器计算值
        Z = 0  # 规范化因子
        e = 0  # 权值误差率
        enum = 0  # 误分类点
        for t in range(len(test)):
            G.append(knn(test[t],k))
            if knn(test[t],k)!=test[t][1]:
                e=e+D[t]*1#计算误差率
                enum=enum+1
        #print(G)
        print('误差率:',round(e,2),'错误点数:',enum)
        f=round(1/2*(np.log(1-e)-np.log(e)),2)#此弱分类器系数
        print("系数：",f)
        flist.append(f)
        for i in range(len(D)):
            Z=Z+D[i]*math.exp(-f*y1[i]*G[i])
        for i in range(len(D)):
            D[i]=D[i]/Z*math.exp(-f*y1[i]*G[i])
        print("更新权值分布：\n",D)

    G1=[]
    print("系数列表：",flist)
    for k in (1, 5):
        g = []
        for t in range(len(test)):
            if knn(test[t], k) == test[t][1]:
               g.append(1)
            else:
               g.append(-1)
        G1.append(g)
    #print(G1)
    result=[]
    y=0
    n=0
    for j in range(len(G1[1])):
        re=0
        for i in range(len(flist)):
             re=re+flist[i]*G1[i][j]
        result.append(re)
    #print(result)
    for i in range(len(result)):
        if result[i]>0 and test[i][1]==1:
            y=y+1
        elif result[i]<0 and test[i][1]==0:
            y=y+1
        else:
            n=n+1
    print("准确率：",y/(y+n))
    print('误分类点个数：',n)

